{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# numpy学习"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1创建"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 用列表或元组创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "[1.+0.j 2.+0.j]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "b = np.array([1,2],dtype=complex)\n",
    "print(a)\n",
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 用内置函数创建内置函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]\n"
     ]
    }
   ],
   "source": [
    "c = np.arange(24).reshape(2,3,4)\n",
    "d = np.linspace(0,1,10,endpoint=False)\n",
    "e = np.logspace(0,4,3,base=2)\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 创建特殊数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0.]\n",
      " [0. 0. 0.]]\n",
      "[[0 0 0]\n",
      " [0 0 0]]\n",
      "[[1 1 1]\n",
      " [1 1 1]]\n",
      "[[0. 0. 0.]\n",
      " [0. 0. 0.]]\n",
      "[[1. 0. 0.]\n",
      " [0. 1. 0.]\n",
      " [0. 0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "print(np.zeros((2,3))) #全0数组\n",
    "print(np.zeros_like(a)) #创建维数与a相同的0数组\n",
    "print(np.ones((2,3),dtype=np.int16)) #全1\n",
    "print(np.empty((2,3))) #空数组,值为随机\n",
    "print(np.eye(3)) #单位阵\n",
    "print(np.random.random((2,3))) #创建随机数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.]\n",
      " [2.]\n",
      " [4.]\n",
      " [6.]]\n",
      "[[0. 1. 2.]]\n",
      "[[ 0.  1.  2.]\n",
      " [ 4.  5.  6.]\n",
      " [ 8.  9. 10.]\n",
      " [12. 13. 14.]]\n",
      "[[0. 0. 0.]\n",
      " [2. 2. 2.]\n",
      " [4. 4. 4.]\n",
      " [6. 6. 6.]]\n",
      "[[0. 1. 2.]\n",
      " [0. 1. 2.]\n",
      " [0. 1. 2.]\n",
      " [0. 1. 2.]]\n"
     ]
    }
   ],
   "source": [
    "#产生能快速广播的数组\n",
    "x,y = np.ogrid[:6:4j, :2:3j] #和arange类似,三个参数是开始值,结束值,步长,步长为虚数表示长度\n",
    "print(x)\n",
    "print(y)\n",
    "print(2*x + y)\n",
    "x,y = np.mgrid[:6:4j, :2:3j] #与ogrid不同的是,它返回的是广播后的数组\n",
    "print(x)\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 从字符串,函数,文件等创建"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.  2.  3.  4.  5.]\n",
      " [ 2.  4.  6.  8. 10.]\n",
      " [ 3.  6.  9. 12. 15.]\n",
      " [ 4.  8. 12. 16. 20.]\n",
      " [ 5. 10. 15. 20. 25.]]\n",
      "[[1. 2. 3.]\n",
      " [4. 5. 6.]]\n",
      "[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]\n",
      "[0 1 2 3 4]\n"
     ]
    }
   ],
   "source": [
    "s = '你好'\n",
    "#print(np.frombuffer(s))\n",
    "\n",
    "print(np.fromfunction(lambda i,j:(i+1)*(j+1), (5,5)))\n",
    "\n",
    "#从文件创建\n",
    "np.savetxt('123.txt',a) #存为文本\n",
    "f = np.loadtxt('123.txt')\n",
    "print(f)\n",
    "\n",
    "#fromfile从二进制文件中创建,tofile写入文件\n",
    "c.tofile('c.bin')\n",
    "c = np.fromfile('c.bin',dtype=np.int32) #读出来是一维的\n",
    "print(c)\n",
    "\n",
    "it = range(5)\n",
    "print(np.fromiter(it, dtype=np.int32)) #从迭代器创建"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 结构体数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(b'zhang', 32, 75.5) (b'wang', 24, 65.2)]\n",
      "[b'zhang' b'wang']\n",
      "32\n"
     ]
    }
   ],
   "source": [
    "person_type = np.dtype({'names':['name','age','weight'], 'formats':['S30','i','f']}, align=True)\n",
    "g = np.array([('zhang',32,75.5), ('wang',24,65.2)], dtype=person_type)\n",
    "print(g)\n",
    "print(g['name'])\n",
    "print(g[0]['age'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6\n",
      "[(1, 2)]\n",
      "[2 5]\n",
      "[[1 3]\n",
      " [4 6]]\n",
      "[4 5 6]\n",
      "[2 5]\n",
      "[1 2 3]\n",
      "[4 5 6]\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n"
     ]
    }
   ],
   "source": [
    "print(a[1,2])\n",
    "index = (1,2)\n",
    "print([index])\n",
    "print(a[0:2,1])\n",
    "print(a[:,[0,2]]) #取第0和2列\n",
    "print(a[1])\n",
    "print(a[...,1])\n",
    "\n",
    "for row in a:\n",
    "    print(row)\n",
    "for element in a.flat:\n",
    "    print(element)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "(2, 3)\n",
      "6\n",
      "int32\n",
      "4\n",
      "<memory at 0x000000000571CBA8>\n"
     ]
    }
   ],
   "source": [
    "print(a.ndim) #维数\n",
    "print(a.shape) #每个维数的长度\n",
    "print(a.size) #元素个数\n",
    "print(a.dtype) #元素类型.所有类型可通过set(np.typeDict.values())查看\n",
    "print(a.itemsize) #每个元素的字节数\n",
    "print(a.data) #缓冲区地址"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4改变形状"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "[[1 4]\n",
      " [2 5]\n",
      " [3 6]]\n",
      "[1 2 3 4 5 6]\n",
      "(2, 3)\n",
      "(4, 2, 3)\n",
      "(2, 3, 1, 4)\n",
      "(2, 3, 4)\n",
      "(4, 6)\n"
     ]
    }
   ],
   "source": [
    "print(a)\n",
    "print(a.T)\n",
    "print(a.ravel()) #展平为1维数组\n",
    "c.shape = 2,3,-1 #-1对应的维自动计算\n",
    "print(a.shape)\n",
    "print(c.transpose(2,0,1).shape)\n",
    "c2 = c[:,:,np.newaxis,:] #增加维度\n",
    "print(c2.shape)\n",
    "print(c2.squeeze().shape) #去掉为1的维度\n",
    "c = c.reshape(4,6) #元素在内存中的位置并没有改变\n",
    "print(c.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5线性代数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 0 0]\n",
      " [0 2 0]\n",
      " [0 0 3]]\n",
      "[1 2 3]\n",
      "转置: [[1. 3.]\n",
      " [2. 4.]]\n",
      "迹: 5.0\n",
      "范数： 5.477225575051661\n",
      "行列式: -2.0000000000000004\n",
      "逆矩阵: [[-2.   1. ]\n",
      " [ 1.5 -0.5]]\n",
      "特征向量和特征值 (array([-0.37228132,  5.37228132]), array([[-0.82456484, -0.41597356],\n",
      "       [ 0.56576746, -0.90937671]]))\n",
      "方程组的解为： [-3.  4.]\n"
     ]
    }
   ],
   "source": [
    "v = np.array([1,2,3])\n",
    "D = np.diag(v)\n",
    "print(D)\n",
    "print(np.diag(D))\n",
    "\n",
    "A = np.array([[1,2],[3,4]], dtype='float')\n",
    "print('转置:',A.transpose())\n",
    "print('迹:',A.trace())\n",
    "print('范数：',np.linalg.norm(A))\n",
    "print('行列式:',np.linalg.det(A))\n",
    "print('逆矩阵:',np.linalg.inv(A))\n",
    "print('特征向量和特征值',np.linalg.eig(A))\n",
    "y = np.array([5,7])\n",
    "print('方程组的解为：',np.linalg.solve(A,y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "False\n",
      "[[1 1 1]\n",
      " [2 2 2]\n",
      " [3 3 3]]\n",
      "[[1 2 3]\n",
      " [1 2 3]\n",
      " [1 2 3]]\n"
     ]
    }
   ],
   "source": [
    "#复制\n",
    "p = a #c跟a完全相同\n",
    "print(p is a)\n",
    "p = a.view() #c跟a虽是不同数组,但c跟a公用数据.\n",
    "print(p is a)\n",
    "p = a.copy() #深拷贝,c跟a完全不同\n",
    "print(p is a)\n",
    "\n",
    "v = np.array([1,2,3])\n",
    "print(v.repeat(3).reshape(3,3))\n",
    "print(np.tile(v,3).reshape(3,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]\n",
      " [0 0 0]\n",
      " [0 0 0]\n",
      " [1 2 3]\n",
      " [4 5 6]]\n",
      "[[1 2 3 0 0 0]\n",
      " [4 5 6 0 0 0]]\n",
      "(2, 2, 3)\n",
      "[array([[1],\n",
      "       [4]]), array([[2],\n",
      "       [5]]), array([[3],\n",
      "       [6]])]\n"
     ]
    }
   ],
   "source": [
    "#组合\n",
    "b = np.zeros_like(a)\n",
    "print(np.concatenate((a,b,a),axis=0)) #axis相加，其余维度相同不变\n",
    "print(np.concatenate((a,b),axis=1))\n",
    "print(np.stack((a,b),axis=1).shape) #所有维度相同，增加新的axis，axis之后的维度顺延\n",
    "#类似还有vstack,hstack, r_, c_\n",
    "\n",
    "#分割\n",
    "print(np.hsplit(a,3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[5]\n",
      " [6]\n",
      " [7]\n",
      " [8]]\n",
      "[[1 2 3]]\n",
      "(4, 1) (1, 3)\n",
      "[[ 5 10 15]\n",
      " [ 6 12 18]\n",
      " [ 7 14 21]\n",
      " [ 8 16 24]]\n"
     ]
    }
   ],
   "source": [
    "u = np.array([5,6,7,8])\n",
    "ax,bx = np.ix_(u,v)\n",
    "print(ax)\n",
    "print(bx)\n",
    "print(ax.shape,bx.shape)\n",
    "print(ax*bx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(array([0, 1]), array([0, 1]))\n",
      "[[-1.  2.]\n",
      " [ 3. -1.]]\n"
     ]
    }
   ],
   "source": [
    "diag = np.diag_indices_from(A)\n",
    "print(diag)\n",
    "A[diag] = -1\n",
    "print(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "[[ True  True  True]\n",
      " [False False False]]\n",
      "True\n",
      "False\n",
      "[[ 1  4  9]\n",
      " [16 25 36]]\n",
      "[[ 3.  6.  9.]\n",
      " [12. 15. 18.]]\n",
      "[[9. 9. 9.]\n",
      " [9. 9. 9.]]\n",
      "[[14 32]\n",
      " [32 77]]\n",
      "[[ 5 10 15]\n",
      " [ 6 12 18]\n",
      " [ 7 14 21]\n",
      " [ 8 16 24]]\n",
      "(24, 210)\n"
     ]
    }
   ],
   "source": [
    "#逻辑运算\n",
    "print(a)\n",
    "b = np.ones((2,3)) *3\n",
    "print(np.logical_or(a==b, a<b))\n",
    "print(np.any(a==b))\n",
    "print(np.all(a>b))\n",
    "\n",
    "#对每个元素操作\n",
    "print(a**2)\n",
    "print(a*b)\n",
    "b *= 3\n",
    "print(b)\n",
    "\n",
    "print(np.inner(a,a)) #计算两个数组最后1维的内积\n",
    "print(np.multiply.outer(u,v)) #先使第一个参数的shape变为(4,1),再multiply,再执行squeeze剔除长度为1的轴\n",
    "c = c.reshape(2,3,4)\n",
    "c2 = np.random.random((5,6,7))\n",
    "print(np.outer(c,c2).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [4 5 6]]\n",
      "6 0\n",
      "21\n",
      "[5 7 9]\n",
      "3.5\n",
      "2.9166666666666665\n",
      "1.707825127659933\n",
      "[[1. 1.]\n",
      " [1. 1.]]\n",
      "[ 6 15]\n",
      "[[ 1  3  6]\n",
      " [ 4  9 15]]\n"
     ]
    }
   ],
   "source": [
    "print(a)\n",
    "print(np.exp(a))\n",
    "print(np.sort(a)) #对每行排序\n",
    "'''\n",
    "当使用ufunc函数对两个数组进行计算时，ufunc函数会对这两个数组的对应元素进行计算，因此它要求这两个数组的形状相同。\n",
    "如果形状不同，会进行如下的广播(broadcasting)处理：\n",
    "1. 让所有输入数组都向其中维数最多的数组看齐，shape属性中不足的部分都通过在前面加1补齐。\n",
    "2. 输出数组的shape属性是输入数组的shape属性的各个轴上的最大值。\n",
    "3. 如果输入数组的某个轴的长度为1或与输出数组的对应轴的长度相同时，这个数组能够用来计算，否则出错。\n",
    "4. 当输入数组的某个轴的长度为1时，沿着此轴运算时都用此轴上的第一组值。\n",
    "'''\n",
    "print(a.max(), a.argmin()) #a.func()等同于np.func(a)\n",
    "print(a.sum())\n",
    "print(a.sum(axis=0)) #也可以对指定的维操作,例如\n",
    "\n",
    "#以下4个为统计函数\n",
    "print(a.mean())\n",
    "print(a.var())\n",
    "print(a.std())\n",
    "print(np.cov(a))\n",
    "\n",
    "print(np.add.reduce(a,axis=1))\n",
    "print(np.add.accumulate(a,axis=1)) #于reduce不同的是它保留中间结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 9稀疏矩阵\n",
    "\n",
    "|类型|描述|优点|缺点|\n",
    "|---|---|---|---|\n",
    "|坐标的列表（COO, sp.coo_matrix）|非0值的行标、列标、元素|方便添加新元素|访问效率低，不适合数学运算|\n",
    "|列表的列表（LIL, sp.lil_matrix）|每行的非0元素的列索引保存在列表中，值保存在另一个列表中|支持切片|不方便数学运算|\n",
    "|值的字典（DOK,sp.dok_matrix）|将非0值保存在字典中，（行，列）作为键|构造简单，且能快速增删查|不方便数学运算|\n",
    "|压缩的列格式（CSC,sp.csc_matrix）|将值与行列索引的数组一起存储|构造复杂|矩阵乘法高效|\n",
    "|压缩的行格式（CSR,sp.csr_matrix）|同上|||\n",
    "|块稀疏矩阵（BSR,cp.bsr_matrix）|与CSR类似，适用于具有稠密子矩阵的稀疏矩阵|对于特定的矩阵有效||\n",
    "|对角矩阵（DIA,sp.dia_matrix）|存储矩阵的对角线元素|仅对对角阵有效||"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0 1 0 0]\n",
      " [2 0 0 3]\n",
      " [0 0 4 0]\n",
      " [5 0 0 0]]\n",
      "5\n",
      "[0 1 1 2 3]\n",
      "[1 2 3 4 5]\n"
     ]
    }
   ],
   "source": [
    "import scipy.sparse as sp\n",
    "\n",
    "v = [1,2,3,4,5]\n",
    "r = [0,1,1,2,3]\n",
    "c = [1,0,3,2,0]\n",
    "A = sp.coo_matrix((v, (r,c)), shape=[4,4])\n",
    "D = A.todense()\n",
    "print(D)\n",
    "print(A.nnz) #非0元素个数\n",
    "print(A.row)\n",
    "print(A.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  (0, 1)\t1\n",
      "  (1, 0)\t2\n",
      "  (1, 3)\t3\n",
      "  (2, 2)\t4\n",
      "  (3, 0)\t5\n",
      "[1 0 3 2 0]\n",
      "[0 1 3 4 5]\n"
     ]
    }
   ],
   "source": [
    "R = A.tocsr()\n",
    "print(R)\n",
    "print(R.indices) #非0元素的列标\n",
    "print(R.indptr) #每行元素的索引起止点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
